using System;
using System.Reflection;

namespace Sedna.Core.Common.Objects.Navigation
{
	/// <summary>
	/// Represents parsed node in the navigation expression.
	/// </summary>
    [Serializable]
    internal class MethodNode : NavigationNode
	{
        private const BindingFlags BINDING_FLAGS
            = BindingFlags.Public | BindingFlags.NonPublic
            | BindingFlags.Instance | BindingFlags.Static
            | BindingFlags.IgnoreCase;

	    
        private string methodName;
        /// <summary>
        /// Creates instance of the node.
        /// </summary>
        /// <param name="parent">Parent node.</param>
        /// <param name="nodeExpression">This node's expression.</param>
		public MethodNode(NavigationNode parent, string nodeExpression) : base(parent, nodeExpression, null)
		{
            ParseNodeExpression(nodeExpression);
		}

	    private void ParseNodeExpression(string nodeExpression)
	    {
            methodName = nodeExpression.Substring(0, nodeExpression.IndexOf('('));
	        //TODO add ability to call method with parameters
	    }
	    
		protected override object GetValueRecursive(bool autoCreate)
		{
            object context = parent.GetValue(autoCreate);
            MethodInfo methodInfo = NodeMethodInfo(context);
            return methodInfo.Invoke(context, new object[] {});
        }
	    
	    private MethodInfo NodeMethodInfo(object context)
	    {
            return context.GetType().GetMethod(methodName, BINDING_FLAGS, null, new Type[] {}, null);   
	    }

        /// <summary>
        /// No sense for <c>MethodNode</c>.
        /// </summary>
        protected override void SetValue(object newValue)
        {
        }
    }
}
